<!-- 流程增改弹窗 -->

<style lang="scss" scoped>
.el-form {
  .hjd-drawer__footer {
    margin-top: 50px;
  }
}

.el-scrollbar {
  ::v-deep .el-scrollbar__wrap {
    overflow-x: hidden;
  }
}

.flow-container {
  height: 100%;

  display: flex;
  flex-direction: column;

  .form {
    flex: 1;
  }

  .buttons {
    padding: 20px;
  }
}

.flow-nodes {
  height: calc(100vh - 320px);

  ::v-deep .el-scrollbar__wrap {
    padding: 0 20px;
  }

  .el-card {
    margin-top: 20px;

    ::v-deep {
      .el-card__header {
        padding: 10px;
      }
    }
  }
}

::v-deep {
  .card-ghost {
    transition: transform 0.18s ease;
    transform: rotateZ(2deg);
  }

  .card-ghost-drop {
    transition: transform 0.18s ease-in-out;
    transform: rotateZ(0deg);
  }

  .drop-preview {
    background-color: rgba(150, 150, 200, 0.1);
    border: 1px dashed #abc;
    margin: 5px;
  }
}

.draggable {
  cursor: move;

  .el-card {
    ::v-deep {
      .el-card__body {
        padding: 10px 20px;

        .el-form .el-form-item {
          margin-top: 10px;
          margin-bottom: 0;
        }
      }
    }
  }
}

.add-flow {
  margin-top: 10px;
}
</style>

<template>
  <el-drawer
    :title="`${type === 'create' ? '新增' : '编辑'}流程`"
    :visible.sync="showDialog"
    size="600px"
    :wrapper-closable="true"
    @close="$emit('update:visible', false)"
  >
    <div class="flow-container">
      <div class="form">
        <el-form
          ref="dataForm"
          :model="form"
          :rules="rules"
          label-width="100px"
          style="margin-left: 20px; margin-right: 20px"
        >
          <el-form-item label="流程名称" prop="flow_name">
            <el-input v-model="form.flow_name" />
          </el-form-item>

          <el-form-item label="流程简介">
            <el-input
              v-model="form.info"
              type="textarea"
              rows="3"
              resize="none"
            />
          </el-form-item>

          <el-row>
            <el-col :span="12">
              <el-form-item label="是否锁定" prop="lock">
                <el-switch v-model="form.lock" />
              </el-form-item>
            </el-col>

            <el-col :span="12">
              <el-form-item label="是否启用" prop="status">
                <el-switch v-model="form.status" />
              </el-form-item>
            </el-col>
          </el-row>

          <el-scrollbar class="flow-nodes">
            <Container
              v-if="visibleContainer"
              group-name="col"
              :drop-placeholder="dropPlaceholderOptions"
              @drop="onDrop"
            >
              <Draggable v-for="(item, index) in form.flow_node" :key="index">
                <div class="draggable">
                  <el-card>
                    <div slot="header" class="node">
                      <span>节点 {{ index + 1 }}</span>
                      <el-button
                        style="float: right; padding: 3px 0"
                        type="text"
                        class="cl_1"
                        @click="form.flow_node.splice(index, 1)"
                      >删除</el-button>
                    </div>

                    <el-row>
                      <el-col :span="12">
                        <el-form-item label="节点名称">
                          <el-input v-model="item.node_name" />
                        </el-form-item>
                      </el-col>

                      <el-col :span="12">
                        <el-form-item label="审核方式">
                          <el-select
                            v-model="item.node_status"
                            @change="nodeStatusChanged(item)"
                          >
                            <el-option label="指定审核人" :value="0" />
                            <el-option label="依次审核" :value="1" />
                            <el-option label="或审" :value="2" />
                          </el-select>
                        </el-form-item>
                      </el-col>

                      <el-col :span="12">
                        <el-form-item label="角色">
                          <el-select
                            v-model="item.role_id"
                            @change="roleChanged(item)"
                          >
                            <el-option
                              v-for="role in roleList"
                              :key="role.role_id"
                              :label="role.name"
                              :value="role.role_id"
                            />
                          </el-select>
                        </el-form-item>
                      </el-col>

                      <el-col :span="12">
                        <el-form-item label="审核人员">
                          <el-select
                            v-if="visibleSelect"
                            v-model="item.reviewer"
                            :multiple="item.node_status !== 0"
                          >
                            <el-option
                              v-for="role in item.adminList"
                              :key="role.uid"
                              :label="role.nick_name"
                              :value="role.uid"
                            />
                          </el-select>
                        </el-form-item>
                      </el-col>

                      <el-col :span="12">
                        <el-form-item label="必须填写理由">
                          <el-switch v-model="item.must_reply" />
                        </el-form-item>
                      </el-col>
                    </el-row>
                  </el-card>
                </div>
              </Draggable>
            </Container>

            <div class="J-flexCC add-flow">
              <el-button type="primary" circle @click="addFlow">
                <i class="el-icon-plus" />
              </el-button>
            </div>
          </el-scrollbar>
        </el-form>
      </div>

      <div class="hjd-drawer__footer buttons">
        <el-button @click="showDialog = false"> 取消 </el-button>
        <el-button type="primary" @click="submit"> 确定 </el-button>
      </div>
    </div>
  </el-drawer>
</template>

<script>
import _ from 'lodash'

import { addFlow, editFlow, flowInfo } from '@/api/flow/manager'
import { handleList as getRoleList } from '@/api/system/auth/role'
import { memberAdmin } from '@/api/member/admin'

import { Container, Draggable } from 'vue-smooth-dnd'

export default {
  components: {
    Container,
    Draggable
  },

  props: {
    visible: {
      type: Boolean,
      default: false
    },
    type: {
      type: String,
      default: 'create'
    },
    data: {
      type: Object,
      default: () => ({})
    }
  },

  data() {
    return {
      showDialog: this.visible,

      visibleSelect: true,
      visibleContainer: true,

      dropPlaceholderOptions: {
        className: 'drop-preview',
        animationDuration: '150',
        showOnTop: true
      },

      defaultItem: {
        node_name: '',
        role_id: '',
        node_status: 0,
        layer: 1,
        must_reply: 1,
        reviewer: ''
      },

      /**
       * 表单内容
       */
      form: {
        flow_name: '',
        info: '',
        flow_node: [],
        lock: 0,
        status: 1
      },

      rules: {
        flow_name: [{ required: true, message: '请填写流程名称' }]
      },

      /**
       * 角色列表
       */
      roleList: [],

      /**
       * 管理员列表
       */
      adminList: [],
      adminListCache: {}
    }
  },

  watch: {
    visible() {
      this.showDialog = this.visible

      if (this.visible) {
        if (this.type === 'edit') {
          // 原始值
          this.form = _.cloneDeep(this.data)
          // 获取 node
          flowInfo({
            flow_id: this.data.flow_id
          }).then(async(res) => {
            this.$set(this.form, 'flow_node', [])
            if (!_.isArray(res.data.node)) return

            for (let i = 0; i < res.data.node.length; i++) {
              const item = res.data.node[i]

              let reviewer
              // === 0 是单选 否则 多选
              if (item.node_status === 0) {
                reviewer = _.get(item.reviewer, '0.uid', '')
              } else {
                reviewer = _.map(item.reviewer, (reviewer) => reviewer.uid)
              }

              // 获取 role_id

              const adminList = await this.getAdminList(item.role_id)

              this.form.flow_node.push({
                node_name: item.node_name,
                role_id: item.role_id,
                node_status: item.node_status,
                layer: item.layer,
                must_reply: item.must_reply,
                reviewer,
                adminList
              })
            }

            // this.resetContainer()
          })
        } else {
          this.addFlow()
        }

        // 清除验证
        const clearValidate = _.get(this.$refs, 'dataForm.clearValidate')
        if (_.isFunction(clearValidate)) clearValidate()
      } else {
        // 关闭
        this.form = {
          flow_name: '',
          info: '',
          flow_node: [],
          lock: 0,
          status: 1
        }
      }
    }
  },

  created() {
    getRoleList().then((res) => {
      this.roleList = res.data.data
    })
  },

  methods: {
    addFlow() {
      this.form.flow_node.push(_.cloneDeep(this.defaultItem))
    },

    removeItem(index) {
      this.form.flow_node.splice(index, 1)
    },

    getAdminList(role_id) {
      if (_.has(this.adminListCache, role_id)) {
        console.log('缓存', role_id, this.adminListCache)
        return this.adminListCache[role_id]
      }

      return memberAdmin({
        role_id,
        status: ''
      }).then((res) => {
        this.adminListCache[role_id] = res.data.data
        return res.data.data
      })
    },

    async roleChanged(item) {
      item.reviewer = ''
      const list = await this.getAdminList(item.role_id)
      this.$set(item, 'adminList', list)
    },

    nodeStatusChanged(item) {
      item.reviewer = ''
      this.visibleSelect = false
      this.$nextTick(() => {
        this.visibleSelect = true
      })
    },

    applyDrag(arr, dragResult) {
      const { removedIndex, addedIndex, payload } = dragResult
      if (removedIndex === null && addedIndex === null) return arr

      const result = [...arr]
      let itemToAdd = payload

      if (removedIndex !== null) {
        itemToAdd = result.splice(removedIndex, 1)[0]
      }

      if (addedIndex !== null) {
        result.splice(addedIndex, 0, itemToAdd)
      }

      return result
    },

    onDrop(dropResult) {
      this.form.flow_node = this.applyDrag(this.form.flow_node, dropResult)
    },

    submit() {
      this.$refs['dataForm'].validate((valid) => {
        if (valid) {
          // 是否是创建
          const isCreate = this.type === 'create'

          // 请求数据
          const queryData = {
            flow_name: this.form.flow_name,
            info: this.form.info,
            flow_node: this.form.flow_node,
            lock: this.form.lock,
            status: this.form.status
          }

          // 修改时传 ID
          if (!isCreate) queryData['flow_id'] = this.data.flow_id

          const flow_node = []
          _.forEach(queryData.flow_node, (item, index) => {
            flow_node.push({
              role_id: item.role_id,
              node_name: item.node_name,
              node_status: item.node_status,
              layer: index + 1,
              must_reply: item.must_reply,
              reviewer: _.isArray(item.reviewer)
                ? _.join(item.reviewer, ',')
                : item.reviewer
            })
          })

          queryData.flow_node = flow_node

          // 请求接口
          const request = isCreate ? addFlow : editFlow
          request(queryData).then(() => {
            this.data.flow_name = this.form.flow_name
            this.data.info = this.form.info
            this.data.flow_node = this.form.flow_node
            this.data.lock = this.form.lock
            this.data.status = this.form.status
            this.showDialog = false
            this.$notify.success(isCreate ? '创建成功' : '修改成功')
            // 刷新列表
            if (isCreate) this.$emit('reload')
          })
        }
      })
    }
  }
}
</script>
